package com.shop.clientorder.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.shop.car.domain.ShopCarDetails;
import com.shop.clientorder.domain.FullAdders;
import com.shop.clientorder.domain.OmsOrder;
import com.shop.clientorder.domain.OmsOrderItem;
import com.shop.common.core.domain.Result;
import com.shop.common.security.utils.SecurityUtils;
import com.shop.product.domain.PmsSkuInfo;
import org.springframework.amqp.core.MessageProperties;
import com.shop.clientorder.domain.OrderItemVo;
import com.shop.clientorder.feign.CouponFeign;
import com.shop.clientorder.feign.ProductRemote;
import com.shop.clientorder.feign.ShopCarRemote;
import com.shop.clientorder.service.IOmsOrderItemService;
import com.shop.clientorder.service.IOmsOrderService;
import com.shop.clientorder.utils.DelayedQueueUtil;
import com.shop.common.redis.service.RedisService;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @Author：作者姓名
 * @Package：com.shop.clientorder.consumer
 * @Project：e-commerce-services
 * @name：MqConsumer
 * @Date：2024/7/14 9:13
 */
@Component
public class MqConsumer {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedisService redisService;
    @Autowired
    private IOmsOrderService omsOrderService;
    @Autowired
    private IOmsOrderItemService omsOrderItemService;
    @Autowired
    private ShopCarRemote shopCarRemote;
    @Autowired
    private ProductRemote productRemote;
    @Autowired
    private DelayedQueueUtil delayedQueueUtil;
    @Autowired
    private CouponFeign couponFeign;

    private final String isConsumption="IS_CONSUMPTION";

    @RabbitListener(queuesToDeclare = @Queue("ORDER_ADD"))
    @Transactional(rollbackFor = Exception.class)
    public void placeOrder(String jsonString, MessageProperties messageProperties, Channel channel){
        OrderItemVo orderItemVo = JSONObject.parseObject(jsonString, OrderItemVo.class);
        String messageId = messageProperties.getMessageId();
        try {
            Long add=redisTemplate.opsForSet().add(isConsumption,messageId);
            if (add>0){
                ArrayList<OmsOrderItem> omsOrderItems = new ArrayList<>();
                //获取订单信息
                OmsOrder omsOrder = orderAdd(orderItemVo);
                CompletableFuture<OmsOrder> omsOrderCompletableFuture = CompletableFuture.supplyAsync(() -> {
                    omsOrderService.addOrder(omsOrder);
                    delayedQueueUtil.sendDelayedQueue("ORDER_DELAYDE",omsOrder,1000*60*15);
                    return omsOrder;
                });
                omsOrderCompletableFuture.thenAcceptAsync(item ->{
                    if (item.getId()>0){
                        omsOrderItems.stream().map(omsOrderItem ->{
                            orderItemAdd(orderItemVo, omsOrder);
                            CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
                                omsOrderItemService.addOrderItem(omsOrderItem);
                            });
                            return voidCompletableFuture;
                        }).collect(Collectors.toList());
                    }
                });
                channel.basicAck(messageProperties.getContentLength(),false);
            }
        }catch (Exception e){
            redisTemplate.opsForSet().remove(isConsumption,messageId);
            try{
                channel.basicReject(messageProperties.getContentLength(),true);
            }catch (IOException ex){
                throw new RuntimeException(ex);
            }
        }
    }

    private OmsOrder orderAdd(OrderItemVo orderItemVo){
        ArrayList<ShopCarDetails> list = new ArrayList<>();
        BigDecimal sum=new BigDecimal(0);
        BigDecimal Percentage=new BigDecimal("0.0001");
        for (String detailsId : orderItemVo.getDetailsIds()) {
            Result<ShopCarDetails> data = shopCarRemote.findShopCarDetails(Long.valueOf(detailsId));
            ShopCarDetails shopCarDetails = data.getData();
            list.add(shopCarDetails);
        }
        for (ShopCarDetails shopCarDetails : list) {
            sum=sum.add(shopCarDetails.getDetailsTotalMoney());
        }
        Long userId = SecurityUtils.getUserId();
        FullAdders fullAdders = omsOrderItemService.FindAddrByUserId(userId);
        OmsOrder omsOrder = new OmsOrder();
        omsOrder.setMemberId(userId);
        omsOrder.setOrderSn(orderItemVo.getOrderSn());
        omsOrder.setMemberUsername(fullAdders.getFullAddersUserName());
        omsOrder.setReceiverProvince(fullAdders.getProvinceName());
        omsOrder.setReceiverCity(fullAdders.getCityName());
        omsOrder.setReceiverRegion(fullAdders.getRegionName());
        omsOrder.setTotalAmount(sum);
        omsOrder.setFreightAmount(sum.multiply(Percentage));
        omsOrder.setCouponAmount(orderItemVo.getCouponAmount());
        omsOrder.setPayType(orderItemVo.getPayType());
        omsOrder.setCouponId(orderItemVo.getCouponId());
        omsOrder.setStatus(0);
        return omsOrder;
    }

    private OmsOrderItem orderItemAdd(OrderItemVo orderItemVo,OmsOrder omsOrder){
        OmsOrderItem omsOrderItem = new OmsOrderItem();
        for (String skuId : orderItemVo.getSkuIds()) {
            Result<PmsSkuInfo> data = productRemote.getSkuInfo(Long.valueOf(skuId));
            PmsSkuInfo pmsSkuInfo = data.getData();
            Long orderId = omsOrderService.findOrderIdByOrderSn(orderItemVo.getOrderSn());
            omsOrderItem.setOrderId(orderId);
            omsOrderItem.setOrderSn(orderItemVo.getOrderSn());
            omsOrderItem.setSkuId(pmsSkuInfo.getSkuId());
            omsOrderItem.setSkuName(pmsSkuInfo.getSkuName());
            omsOrderItem.setSkuPic(pmsSkuInfo.getSkuDefaultImg());
            omsOrderItem.setSkuPrice(pmsSkuInfo.getPrice());
            omsOrderItem.setSkuQuantity(orderItemVo.getTotalCount());
        }
        return omsOrderItem;
    }
}
